home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / program / 316 / libsrc / opendir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-10-20  |  4.5 KB  |  216 lines

  1. /*
  2.  *        Cross Development System for Atari ST 
  3.  *     Copyright (c) 1988, Memorial University of Newfoundland
  4.  *
  5.  *  A public domain implementation of BSD directory routines for MS-DOS/atari.
  6.  *  Written by Michael Rendell ({uunet,utai}michael@garfield), August 1897
  7.  *
  8.  * $Header: opendir.c,v 1.2 88/01/29 18:03:58 m68k Exp $
  9.  *
  10.  * jrd 1.2
  11.  *
  12.  * $Log:    opendir.c,v $
  13.  * Revision 1.1  88/01/29  18:03:58  m68k
  14.  * Initial revision
  15.  * 
  16.  */
  17. #ifdef gem
  18. #define GEMDOS
  19. # include <types.h>
  20. # include <stat.h>
  21. # include <dir.h>
  22. # include <param.h>
  23. # include <osbind.h>
  24. #else /* !GEMDOS */
  25. # include <sys/types.h>
  26. # include <sys/stat.h>
  27. # include <sys/dir.h>
  28. # ifdef    MSDOS
  29. # include    <dos.h>
  30. # endif    /* MSDOS */
  31. #endif    /* GEMDOS */
  32. #include    <memory.h>
  33. #include    <string.h>
  34.  
  35. #ifndef    NULL
  36. # define    NULL    0
  37. #endif    /* NULL */
  38.  
  39. #ifndef    MAXPATHLEN
  40. # define    MAXPATHLEN    67
  41. #endif    /* MAXPATHLEN */
  42.  
  43. #ifdef    MSDOS
  44. /* file attribute stuff */
  45. #define    FA_RONLY    0x01
  46. #define    FA_HIDDEN    0x02
  47. #define    FA_SYSTEM    0x04
  48. #define    FA_LABEL    0x08
  49. #define    FA_DIR        0x10
  50. #define    FA_ARCHIVE    0x20
  51.  
  52. /* dos call values */
  53. #define    DOSI_FINDF    0x4e
  54. #define    DOSI_FINDN    0x4f
  55. #define    DOSI_SDTA    0x1a
  56.  
  57. /* what find first/next calls look use */
  58. struct _dta {
  59.     char        dta_buf[21];
  60.     char        dta_attribute;
  61.     unsigned short    dta_time;
  62.     unsigned short    dta_date;
  63.     long        dta_size;
  64.     char        dta_name[14];
  65. };
  66. #endif    /* MSDOS */
  67.  
  68. #define    Newisnull(a, t)        ((a = (t *) malloc((u_long) sizeof(t))) == (t *) NULL)
  69. #define    ATTRIBUTES        (FA_DIR | FA_HIDDEN | FA_SYSTEM)
  70.  
  71.  
  72. static    char    *getdirent();
  73. static    void    setdta();
  74.  
  75. static    struct _dta    dtabuf;
  76. #ifdef    MSDOS
  77. static    struct _dta    *dtapnt = &dtabuf;
  78. static    union REGS    reg, nreg;
  79.  
  80. # if    defined(M_I86LM)
  81. static    struct SREGS    sreg;
  82. # endif
  83. #endif    /* MSDOS */
  84.  
  85. DIR    *
  86. opendir(name)
  87.     char    *name;
  88. {
  89.     DIR            *dirp;
  90.     char            c;
  91.     char            *s;
  92.     struct _dircontents    *dp;
  93.     char            nbuf[MAXPATHLEN + 1];
  94.     
  95. #ifdef    MSDOS
  96.     {
  97.         struct    stat        statb;
  98.  
  99.         if (stat(name, &statb) < 0
  100.             || (statb.st_mode & S_IFMT) != S_IFDIR)
  101.                 return (DIR *) NULL;
  102.         setdta();
  103.     }
  104. #endif    /* MSDOS */
  105. #ifdef    GEMDOS
  106.     {
  107.         /* This bit of nastyness is due to the fact that Fattrib()
  108.          * does not do as it is ment to - i.e. it always fails when
  109.          * used on directories.  Piss me off!
  110.          */
  111.         if (index(name, '*') || index(name, '?'))
  112.             return (DIR *) NULL;
  113.         setdta();
  114.         if (getdirent(name) == (char *) NULL ||
  115.             !(dtabuf.dta_attribute & FA_DIR))
  116.                 return (DIR *) NULL;
  117.     }
  118. #endif    /* GEMDOS */
  119.     if (Newisnull(dirp, DIR))
  120.         return (DIR *) NULL;
  121.     if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  122.         (void) strcat(strcpy(nbuf, name), "\\*.*");
  123.     else
  124.         (void) strcat(strcpy(nbuf, name), "*.*");
  125.     dirp->dd_loc = 0;
  126.     dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  127.     if ((s = getdirent(nbuf)) == (char *) NULL)
  128.         return dirp;
  129.     do {
  130.         if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  131.             malloc((u_long) (strlen(s) + 1))) == (char *) NULL)
  132.         {
  133.             if (dp)
  134.                 free((char *) dp);
  135.             closedir(dirp);
  136.             return (DIR *) NULL;
  137.         }
  138.         if (dirp->dd_contents)
  139.             dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  140.         else
  141.             dirp->dd_contents = dirp->dd_cp = dp;
  142.         (void) strcpy(dp->_d_entry, s);
  143.         dp->_d_next = (struct _dircontents *) NULL;
  144.     } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  145.     dirp->dd_cp = dirp->dd_contents;
  146.  
  147.     return dirp;
  148. }
  149.  
  150. #ifdef    MSDOS
  151. static    char    *
  152. getdirent(dir)
  153.     char    *dir;
  154. {
  155.     if (dir != (char *) NULL) {        /* get first entry */
  156.         reg.h.ah = DOSI_FINDF;
  157.         reg.h.cl = ATTRIBUTES;
  158. # if    defined(M_I86LM)
  159.         reg.x.dx = FP_OFF(dir);
  160.         sreg.ds = FP_SEG(dir);
  161. # else
  162.         reg.x.dx = (unsigned) dir;
  163. # endif
  164.     } else {                /* get next entry */
  165.         reg.h.ah = DOSI_FINDN;
  166. # if    defined(M_I86LM)
  167.         reg.x.dx = FP_OFF(dtapnt);
  168.         sreg.ds = FP_SEG(dtapnt);
  169. # else
  170.         reg.x.dx = (unsigned) dtapnt;
  171. # endif
  172.     }
  173. # if    defined(M_I86LM)
  174.     intdosx(®, &nreg, &sreg);
  175. # else
  176.     intdos(®, &nreg);
  177. # endif
  178.     if (nreg.x.cflag)
  179.         return (char *) NULL;
  180.  
  181.     return dtabuf.dta_name;
  182. }
  183.  
  184. static    void
  185. setdta()
  186. {
  187.     reg.h.ah = DOSI_SDTA;
  188. # if    defined(M_I86LM)
  189.     reg.x.dx = FP_OFF(dtapnt);
  190.     sreg.ds = FP_SEG(dtapnt);
  191.     intdosx(®, &nreg, &sreg);
  192. # else
  193.     reg.x.dx = (int) dtapnt;
  194.     intdos(®, &nreg);
  195. # endif
  196. }
  197. #endif    /* MSDOS */
  198.  
  199. #ifdef    GEMDOS
  200. static    char    *
  201. getdirent(dir)
  202.     char    *dir;
  203. {
  204.     if (dir ? Fsfirst(dir, ATTRIBUTES) : Fsnext())
  205.         return (char *) NULL;
  206.  
  207.     return dtabuf.dta_name;
  208. }
  209.  
  210. static    void
  211. setdta()
  212. {
  213.     Fsetdta((char *) &dtabuf);
  214. }
  215. #endif    /* GEMDOS */
  216.